home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / Mesa-3.0 / widgets-mesa / SRC / MesaWorkstation.c < prev   
Encoding:
C/C++ Source or Header  |  1998-03-28  |  19.7 KB  |  837 lines

  1. /* MesaWorkstation.c -- Implementation file for the Mesa Workstation widget
  2.    Copyright (C) 1995 Thorsten.Ohl @ Physik.TH-Darmstadt.de
  3.  
  4.    This library is free software; you can redistribute it and/or
  5.    modify it under the terms of the GNU Library General Public
  6.    License as published by the Free Software Foundation; either
  7.    version 2 of the License, or (at your option) any later version.
  8.  
  9.    This library is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU Library General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU Library General Public
  15.    License along with this library; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18.    $Id: MesaWorkstation.c,v 1.21 1996/09/30 00:21:07 ohl Exp $
  19.  */
  20.  
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <math.h>
  24. #include <X11/IntrinsicP.h>
  25. #include <X11/StringDefs.h>
  26. #include <GL/glu.h>
  27. #include <GL/xmesa.h>
  28. #ifdef __GLX_MOTIF
  29. #include <GL/MesaMWorkstationP.h>
  30. #else
  31. #include <GL/MesaWorkstationP.h>
  32. #endif
  33.  
  34. #if STDC_HEADERS
  35. # include <string.h>
  36. #else
  37. # ifndef HAVE_STRCHR
  38. #  define strchr index
  39. #  define strrchr rindex
  40. # endif
  41. char *strchr (), *strrchr ();
  42. # ifndef HAVE_MEMCPY
  43. #  define memcpy(d, s, n) bcopy ((s), (d), (n))
  44. # endif
  45. # ifndef HAVE_MEMMOVE
  46. #  define memmove(d, s, n) bcopy ((s), (d), (n))
  47. # endif
  48. #endif
  49.  
  50. #ifndef M_PI
  51. #define M_PI 3.14159265358979323846
  52. #endif
  53.  
  54. #ifdef __GLX_MOTIF
  55. #define GLwDrawingAreaWidget       GLwMDrawingAreaWidget
  56. #define GLwDrawingAreaClassRec     GLwMDrawingAreaClassRec
  57. #define GLwDrawingAreaRec          GLwMDrawingAreaRec
  58. #define glwDrawingAreaClassRec     glwMDrawingAreaClassRec
  59. #define glwDrawingAreaWidgetClass  glwMDrawingAreaWidgetClass
  60. #define MesaDrawingAreaWidget      MesaMDrawingAreaWidget
  61. #define MesaDrawingAreaClassRec    MesaMDrawingAreaClassRec
  62. #define MesaDrawingAreaRec         MesaMDrawingAreaRec
  63. #define mesaDrawingAreaClassRec    mesaMDrawingAreaClassRec
  64. #define mesaDrawingAreaWidgetClass mesaMDrawingAreaWidgetClass
  65. #define MesaWorkstationWidget      MesaMWorkstationWidget
  66. #define MesaWorkstationClassRec    MesaMWorkstationClassRec
  67. #define MesaWorkstationRec         MesaMWorkstationRec
  68. #define mesaWorkstationClassRec    mesaMWorkstationClassRec
  69. #define mesaWorkstationWidgetClass mesaMWorkstationWidgetClass
  70. #define GLwPostObject           GLwMPostObject
  71. #define GLwUnpostObject           GLwMUnpostObject
  72. #define GLwUnpostAllObjects       GLwMUnpostAllObjects
  73. #define GLwBeginView           GLwMBeginView
  74. #define GLwEndView           GLwMEndView
  75. #define GLwPostViewList           GLwMPostViewList
  76. #define GLwPostViewMatrix       GLwMPostViewMatrix
  77. #define GLwPostCurrentView       GLwMPostCurrentView
  78. #define GLwUnpostView           GLwMUnpostView
  79. #define GLwSetPolarView           GLwMSetPolarView
  80. #define GLwGetViewList           GLwMGetViewList
  81. #define GLwGetViewMatrix       GLwMGetViewMatrix
  82. #define GLwBeginProjection       GLwMBeginProjection
  83. #define GLwEndProjection       GLwMEndProjection
  84. #define GLwPostProjectionList       GLwMPostProjectionList
  85. #define GLwPostProjectionMatrix       GLwMPostProjectionMatrix
  86. #define GLwPostCurrentProjection   GLwMPostCurrentProjection
  87. #define GLwUnpostProjection       GLwMUnpostProjection
  88. #define GLwSetFrustumProjection       GLwMSetFrustumProjection
  89. #define GLwSetOrthoProjection       GLwMSetOrthoProjection
  90. #define GLwGetProjectionList       GLwMGetProjectionList
  91. #define GLwGetProjectionMatrix       GLwMGetProjectionMatrix
  92. #define GLwRedrawObjects       GLwMRedrawObjects
  93. #define GLwPostView           GLwMPostView
  94. #define GLwGetView           GLwMGetView
  95. #define GLwPostProjection       GLwMPostProjection
  96. #define GLwGetProjection       GLwMGetProjection
  97. #define GLwMakeCurrent             GLwMMakeCurrent
  98. #endif
  99.  
  100. #define MesaProjection(_widget) \
  101.    (((MesaWorkstationWidget)_widget)->mesaWorkstation.projection)
  102. #define MesaView(_widget) \
  103.    (((MesaWorkstationWidget)_widget)->mesaWorkstation.view)
  104. #define MesaNextObject(_widget) \
  105.    (((MesaWorkstationWidget)_widget)->mesaWorkstation.next_object)
  106. #define MesaAllocatedObjects(_widget) \
  107.    (((MesaWorkstationWidget)_widget)->mesaWorkstation.allocated_objects)
  108. #define MesaObjects(_widget) \
  109.    (((MesaWorkstationWidget)_widget)->mesaWorkstation.objects)
  110.  
  111.  
  112. /* Private utility functions. */
  113.  
  114.  
  115. /* Resources. */
  116.  
  117.  
  118. /* Actions and their translations. */
  119.  
  120. static void
  121. Projection (Widget w, XEvent *event, String *argv, Cardinal *argc)
  122. {
  123.   LOG (w);
  124.  
  125.   if (*argc == 0)
  126.     return;
  127.  
  128.   if ((MesaProjection(w).type != FRUSTUM)
  129.       && (MesaProjection(w).type != ORTHO))
  130.     return;
  131.  
  132.   switch (*argv[0])
  133.     {
  134.     case 'p':
  135.       MesaProjection(w).type = FRUSTUM;
  136.       break;
  137.     case 'o':
  138.       MesaProjection(w).type = ORTHO;
  139.       break;
  140.     case 'l':
  141.       MesaProjection(w).u.vol.left *= 1.1;
  142.       break;
  143.     case 'L':
  144.       MesaProjection(w).u.vol.left /= 1.1;
  145.       break;
  146.     case 'r':
  147.       MesaProjection(w).u.vol.right *= 1.1;
  148.       break;
  149.     case 'R':
  150.       MesaProjection(w).u.vol.right /= 1.1;
  151.       break;
  152.     case 'b':
  153.       MesaProjection(w).u.vol.bottom *= 1.1;
  154.       break;
  155.     case 'B':
  156.       MesaProjection(w).u.vol.bottom /= 1.1;
  157.       break;
  158.     case 't':
  159.       MesaProjection(w).u.vol.top *= 1.1;
  160.       break;
  161.     case 'T':
  162.       MesaProjection(w).u.vol.top /= 1.1;
  163.       break;
  164.     case 'n':
  165.       MesaProjection(w).u.vol.near *= 1.1;
  166.       break;
  167.     case 'N':
  168.       MesaProjection(w).u.vol.near /= 1.1;
  169.       break;
  170.     case 'f':
  171.       MesaProjection(w).u.vol.far *= 1.1;
  172.       break;
  173.     case 'F':
  174.       MesaProjection(w).u.vol.far /= 1.1;
  175.       break;
  176.     case 'a':
  177.       MesaProjection(w).u.vol.left *= 1.1;
  178.       MesaProjection(w).u.vol.right *= 1.1;
  179.       MesaProjection(w).u.vol.bottom *= 1.1;
  180.       MesaProjection(w).u.vol.top *= 1.1;
  181.       break;
  182.     case 'A':
  183.       MesaProjection(w).u.vol.left /= 1.1;
  184.       MesaProjection(w).u.vol.right /= 1.1;
  185.       MesaProjection(w).u.vol.bottom /= 1.1;
  186.       MesaProjection(w).u.vol.top /= 1.1;
  187.       break;
  188.     }
  189.  
  190.   GLwRedrawObjects (w);
  191. }
  192.  
  193. static void
  194. Move (Widget w, XEvent *event, String *argv, Cardinal *argc)
  195. {
  196.   double scale = 0.01;
  197.   LOG (w);
  198.  
  199.   if (*argc == 0)
  200.     return;
  201.  
  202.   if (MesaView(w).type != POLAR)
  203.     return;
  204.  
  205.   if (*argc >= 2)
  206.     scale *= atof (argv[1]);
  207.  
  208.   switch (*argv[0])
  209.     {
  210.     case '+':
  211.       MesaView(w).u.polar.r /= 1.1;
  212.       break;
  213.     case '-':
  214.       MesaView(w).u.polar.r *= 1.1;
  215.       break;
  216.     case 'l':
  217.       MesaView(w).u.polar.phi += scale * M_PI;
  218.       break;
  219.     case 'r':
  220.       MesaView(w).u.polar.phi -= scale * M_PI;
  221.       break;
  222.     case 'u':
  223.       MesaView(w).u.polar.theta -= scale * M_PI;
  224.       break;
  225.     case 'd':
  226.       MesaView(w).u.polar.theta += scale * M_PI;
  227.       break;
  228.     }
  229.  
  230.   GLwRedrawObjects (w);
  231. }
  232.  
  233. static XtActionsRec actions[] =
  234. {
  235.   /* {name, procedure} */
  236.   {"Move", Move },
  237.   {"Projection", Projection },
  238. };
  239.  
  240. static char translations[] =
  241. #ifdef __GLX_MOTIF
  242. "~Shift<Key>osfLeft: Move(l)\n\
  243. Shift<Key>osfLeft: Move(l,10)\n\
  244. ~Shift<Key>osfRight: Move(r)\n\
  245. Shift<Key>osfRight: Move(r,10)\n\
  246. ~Shift<Key>osfUp: Move(u)\n\
  247. Shift<Key>osfUp: Move(u,10)\n\
  248. ~Shift<Key>osfDown: Move(d)\n\
  249. Shift<Key>osfDown: Move(d,10)\n\
  250. ~Shift<Key>Left: Move(l)\n\
  251. Shift<Key>Left: Move(l,10)\n\
  252. ~Shift<Key>Right: Move(r)\n\
  253. Shift<Key>Right: Move(r,10)\n\
  254. ~Shift<Key>Up: Move(u)\n\
  255. Shift<Key>Up: Move(u,10)\n\
  256. ~Shift<Key>Down: Move(d)\n\
  257. Shift<Key>Down: Move(d,10)\n\
  258. <Key>plus: Move(+)\n\
  259. <Key>minus: Move(-)\n\
  260. ~Shift<Key>l: Projection(l)\n\
  261. Shift<Key>l: Projection(L)\n\
  262. ~Shift<Key>r: Projection(r)\n\
  263. Shift<Key>r: Projection(R)\n\
  264. ~Shift<Key>b: Projection(b)\n\
  265. Shift<Key>b: Projection(B)\n\
  266. ~Shift<Key>t: Projection(t)\n\
  267. Shift<Key>t: Projection(T)\n\
  268. ~Shift<Key>n: Projection(n)\n\
  269. Shift<Key>n: Projection(N)\n\
  270. ~Shift<Key>f: Projection(f)\n\
  271. Shift<Key>f: Projection(F)\n\
  272. ~Shift<Key>a: Projection(a)\n\
  273. Shift<Key>a: Projection(A)\n\
  274. <Key>p: Projection(p)\n\
  275. <Key>o: Projection(o)\n";
  276. #else /* __GLX_MOTIF */
  277. "~Shift<Key>Left: Move(l)\n\
  278. Shift<Key>Left: Move(l,10)\n\
  279. ~Shift<Key>Right: Move(r)\n\
  280. Shift<Key>Right: Move(r,10)\n\
  281. ~Shift<Key>Up: Move(u)\n\
  282. Shift<Key>Up: Move(u,10)\n\
  283. ~Shift<Key>Down: Move(d)\n\
  284. Shift<Key>Down: Move(d,10)\n\
  285. <Key>plus: Move(+)\n\
  286. <Key>minus: Move(-)\n\
  287. ~Shift<Key>l: Projection(l)\n\
  288. Shift<Key>l: Projection(L)\n\
  289. ~Shift<Key>r: Projection(r)\n\
  290. Shift<Key>r: Projection(R)\n\
  291. ~Shift<Key>b: Projection(b)\n\
  292. Shift<Key>b: Projection(B)\n\
  293. ~Shift<Key>t: Projection(t)\n\
  294. Shift<Key>t: Projection(T)\n\
  295. ~Shift<Key>n: Projection(n)\n\
  296. Shift<Key>n: Projection(N)\n\
  297. ~Shift<Key>f: Projection(f)\n\
  298. Shift<Key>f: Projection(F)\n\
  299. ~Shift<Key>a: Projection(a)\n\
  300. Shift<Key>a: Projection(A)\n\
  301. <Key>p: Projection(p)\n\
  302. <Key>o: Projection(o)\n";
  303. #endif /* __GLX_MOTIF */
  304.  
  305.  
  306. /* Basic widget methods.  */
  307.  
  308. #define OBJECT_CHUNK_SIZE 10
  309.  
  310. static void
  311. Initialize (Widget request, Widget new, ArgList args, Cardinal * num_args)
  312. {
  313.   LOG (new);
  314.   MesaAllocatedObjects (new) = OBJECT_CHUNK_SIZE;
  315.   MesaObjects (new) = (GLuint *)
  316.     XtCalloc (MesaAllocatedObjects (new), sizeof (GLuint));
  317.   MesaNextObject (new) = MesaObjects (new);
  318.   MesaView(new).type = NOVIEW;
  319.   MesaView(new).list = 0;
  320.   MesaProjection(new).type = NOPROJ;
  321.   MesaProjection(new).list = 0;
  322. }
  323.  
  324. #if 0
  325. static void
  326. Realize (Widget w, XtValueMask * mask,
  327.      XSetWindowAttributes * attr)
  328. {
  329.   LOG (w);
  330.   (XtSuperclass (w)->core_class.realize) (w, mask, attr);
  331. }
  332. #endif
  333.  
  334. static void
  335. Destroy (Widget w)
  336. {
  337.   LOG (w);
  338.   XtFree ((char *) MesaObjects (w));
  339. }
  340.  
  341. static void
  342. Redisplay (Widget w, XEvent *event, Region region)
  343. {
  344.   LOG (w);
  345.   if (event->xexpose.count == 0)    /* last Expose event */
  346.     GLwRedrawObjects (w);
  347. }
  348.  
  349.  
  350. /* Now use all these methods in the widget class record.  */
  351.  
  352. MesaWorkstationClassRec mesaWorkstationClassRec =
  353. {
  354.   {
  355.     /* superclass            */ (WidgetClass) &mesaDrawingAreaClassRec,
  356. #ifdef __GLX_MOTIF
  357.     /* class_name            */ "MesaMWorkstation",
  358. #else
  359.     /* class_name            */ "MesaWorkstation",
  360. #endif
  361.     /* widget_size           */ sizeof (MesaWorkstationRec),
  362.     /* class_initialize      */ NULL,
  363.     /* class_part_initialize */ NULL,
  364.     /* class_inited          */ FALSE,
  365.     /* initialize            */ Initialize,
  366.     /* initialize_hook       */ NULL,
  367.     /* realize               */ XtInheritRealize,
  368.     /* actions               */ actions,
  369.     /* num_actions           */ XtNumber (actions),
  370.     /* resources             */ NULL,
  371.     /* num_resources         */ 0,
  372.     /* xrm_class             */ NULLQUARK,
  373.     /* compress_motion       */ TRUE,
  374.     /* compress_exposure     */ TRUE,
  375.     /* compress_enterleave   */ TRUE,
  376.     /* visible_interest      */ FALSE,
  377.     /* destroy               */ Destroy,
  378.     /* resize                */ XtInheritResize,
  379.     /* expose                */ Redisplay,
  380.     /* set_values            */ NULL,
  381.     /* set_values_hook       */ NULL,
  382.     /* set_values_almost     */ XtInheritSetValuesAlmost,
  383.     /* get_values_hook       */ NULL,
  384.     /* accept_focus          */ NULL,
  385.     /* version               */ XtVersion,
  386.     /* callback_private      */ NULL,
  387.     /* tm_table              */ translations,
  388.     /* query_geometry        */ XtInheritQueryGeometry,
  389.     /* display_accelerator   */ XtInheritDisplayAccelerator,
  390.     /* extension             */ NULL
  391.   },
  392. #ifdef __GLX_MOTIF
  393.   { /* XmPrimitive fields */
  394.     /* border_highlight      */ (XtWidgetProc) _XtInherit,
  395.     /* border_unhighlight    */ (XtWidgetProc) _XtInherit,
  396.     /* translations          */ XtInheritTranslations,
  397.     /* arm_and_activate      */ NULL,
  398.     /* get_resources         */ NULL,
  399.     /* num get_resources     */ 0,
  400.     /* extension             */ NULL,
  401.   },
  402. #endif /* __GLX_MOTIF */
  403.   { /* MesaDrawingArea fields*/
  404.     /* RCS_id                */ NULL
  405.   },
  406.   { /* MesaWorkstation fields*/
  407.     /* RCS_id                */
  408.     "@(#) $Id: MesaWorkstation.c,v 1.21 1996/09/30 00:21:07 ohl Exp $"
  409.   }
  410. };
  411. WidgetClass mesaWorkstationWidgetClass
  412.   = (WidgetClass) & mesaWorkstationClassRec;
  413.  
  414.  
  415. /* More private utility functions. */
  416.  
  417. static int
  418. is_workstation (Widget w)
  419. {
  420.   if (XtClass (w) != mesaWorkstationWidgetClass)
  421.     {
  422.       XtAppError (XtWidgetToApplicationContext (w),
  423. #ifndef __GLX_MOTIF
  424.           "Not a Mesa Workstation!");
  425. #else
  426.           "Not a Mesa/Motif Workstation!");
  427. #endif
  428.       return 0;
  429.     }
  430.   else
  431.     return 1;
  432. }
  433.  
  434. static void
  435. mesa_frustum (volume v)
  436. {
  437.   glFrustum (v.left, v.right, v.bottom, v.top, v.near, v.far);
  438. }
  439.  
  440. static void
  441. mesa_ortho (volume v)
  442. {
  443.   glOrtho (v.left, v.right, v.bottom, v.top, v.near, v.far);
  444. }
  445.  
  446. static void
  447. mesa_look_at (look_at l)
  448. {
  449.   gluLookAt (l.eyex, l.eyex, l.eyez,
  450.          l.ctrx, l.ctrx, l.ctrz,
  451.          l.upx, l.upx, l.upz);
  452. }
  453.  
  454.  
  455. static void
  456. mesa_polar (polar p)
  457. {
  458.   GLdouble r, sin_th, cos_th, sin_phi, cos_phi, u_sin_th, u_cos_th;
  459.   r = p.r;
  460.   sin_th = sin (p.theta);
  461.   cos_th = cos (p.theta);
  462.   sin_phi = sin (p.phi);
  463.   cos_phi = cos (p.phi);
  464.   u_sin_th = cos_th;
  465.   u_cos_th = -sin_th;
  466.   gluLookAt (r*sin_th*cos_phi, r*cos_th, r*sin_th*sin_phi,
  467.          0.0, 0.0, 0.0,
  468.          u_sin_th*cos_phi, u_cos_th, u_sin_th*sin_phi);
  469. }
  470.  
  471.  
  472. /* Exported utilility functions.  */
  473. void
  474. GLwPostObject (Widget w, GLuint object)
  475. {
  476.   if (is_workstation (w))
  477.     {
  478.       if (MesaNextObject (w) > MesaObjects (w) + MesaAllocatedObjects (w))
  479.     {
  480.       MesaAllocatedObjects (w) += OBJECT_CHUNK_SIZE;
  481.       MesaObjects (w) = (GLuint *)
  482.         XtRealloc ((char *) MesaObjects (w),
  483.                sizeof (GLuint) * MesaAllocatedObjects (w));
  484.     }
  485.       *(MesaNextObject(w)++) = object;
  486.     }
  487. }
  488.  
  489. void
  490. GLwUnpostObject (Widget w, GLuint object)
  491. {
  492.   if (is_workstation (w))
  493.     {
  494.       GLuint *p;
  495.       for (p = MesaObjects (w); p < MesaNextObject (w); p++)
  496.     if (*p == object)
  497.       {
  498.         memmove (p, p + 1,
  499.              sizeof (GLuint) * (MesaNextObject (w) - p - 1));
  500.         MesaNextObject(w)--;
  501.         break;
  502.       }
  503.     }
  504. }
  505.  
  506. void
  507. GLwUnpostAllObjects (Widget w)
  508. {
  509.   if (is_workstation (w))
  510.     MesaNextObject (w) = MesaObjects (w);
  511. }
  512.  
  513. void
  514. GLwBeginView (Widget w)
  515. {
  516.   if (is_workstation (w))
  517.     {
  518.       MesaView(w).type = VIEW_LIST;
  519.       if (!glIsList (MesaView(w).list))
  520.     MesaView(w).list = glGenLists (1);
  521.       glNewList (MesaView(w).list, GL_COMPILE);
  522.     }
  523. }
  524.  
  525. void
  526. GLwEndView (void)
  527. {
  528.   glEndList ();
  529. }
  530.  
  531. void
  532. GLwPostViewList (Widget w, GLuint view)
  533. {
  534.   if (is_workstation (w))
  535.     {
  536.       MesaView(w).type = VIEW_LIST;
  537.       MesaView(w).list = view;
  538.     }
  539. }
  540.  
  541. void
  542. GLwPostViewMatrix (Widget w, GLdouble *m)
  543. {
  544.   if (is_workstation (w))
  545.     {
  546.       MesaView(w).type = VIEW_MATRIX;
  547.       memcpy (MesaView(w).u.m, m, sizeof (MesaView(w).u.m));
  548.     }
  549. }
  550.  
  551. void
  552. GLwPostCurrentView (Widget w)
  553. {
  554.   if (is_workstation (w))
  555.     {
  556.       MesaView(w).type = VIEW_MATRIX;
  557.       glGetDoublev (GL_MODELVIEW_MATRIX, MesaView(w).u.m);
  558.     }
  559. }
  560.  
  561. void
  562. GLwUnpostView (Widget w)
  563. {
  564.   if (is_workstation (w))
  565.     MesaView(w).type = NOVIEW;
  566. }
  567.  
  568. void
  569. GLwSetPolarView (Widget w, GLdouble r, GLdouble theta, GLdouble phi)
  570. {
  571.   if (is_workstation (w))
  572.     {
  573.       MesaView(w).type = POLAR;
  574.       MesaView(w).u.polar.r = r;
  575.       MesaView(w).u.polar.theta = theta;
  576.       MesaView(w).u.polar.phi = phi;
  577.     }
  578. }
  579.  
  580. GLuint
  581. GLwGetViewList (Widget w)
  582. {
  583.   if (is_workstation (w))
  584.     {
  585.       if (MesaView(w).type == VIEW_LIST)
  586.     return MesaView(w).list;
  587.     }
  588.   return 0;
  589. }
  590.  
  591. int
  592. GLwGetViewMatrix (Widget w, GLdouble *m)
  593. {
  594.   if (is_workstation (w))
  595.     {
  596.       if (MesaView(w).type == VIEW_MATRIX)
  597.     memcpy (m, MesaView(w).u.m, sizeof (MesaView(w).u.m));
  598.       return 1;
  599.     }
  600.   return 0;
  601. }
  602.  
  603. void
  604. GLwBeginProjection (Widget w)
  605. {
  606.   if (is_workstation (w))
  607.     {
  608.       MesaProjection(w).type = PROJ_LIST;
  609.       if (!glIsList (MesaProjection(w).list))
  610.     MesaProjection(w).list = glGenLists (1);
  611.       glNewList (MesaProjection(w).list, GL_COMPILE);
  612.     }
  613. }
  614.  
  615. void
  616. GLwEndProjection (void)
  617. {
  618.   glEndList ();
  619. }
  620.  
  621. void
  622. GLwPostProjectionList (Widget w, GLuint proj)
  623. {
  624.   if (is_workstation (w))
  625.     {
  626.       MesaProjection(w).type = PROJ_LIST;
  627.       MesaProjection(w).list = proj;
  628.     }
  629. }
  630.  
  631. void
  632. GLwPostProjectionMatrix (Widget w, GLdouble *m)
  633. {
  634.   if (is_workstation (w))
  635.     {
  636.       MesaProjection(w).type = PROJ_MATRIX;
  637.       memcpy (MesaProjection(w).u.m, m, sizeof (MesaProjection(w).u.m));
  638.     }
  639. }
  640.  
  641. void
  642. GLwPostCurrentProjection (Widget w)
  643. {
  644.   if (is_workstation (w))
  645.     {
  646.       MesaProjection(w).type = PROJ_MATRIX;
  647.       glGetDoublev (GL_PROJECTION_MATRIX, MesaProjection(w).u.m);
  648.     }
  649. }
  650.  
  651. void
  652. GLwUnpostProjection (Widget w)
  653. {
  654.   if (is_workstation (w))
  655.     MesaProjection(w).type = NOPROJ;
  656. }
  657.  
  658. void
  659. GLwSetFrustumProjection (Widget w,
  660.              GLdouble left, GLdouble right,
  661.              GLdouble bottom, GLdouble top,
  662.              GLdouble near, GLdouble far)
  663. {
  664.   if (is_workstation (w))
  665.     {
  666.       MesaProjection(w).type = FRUSTUM;
  667.       MesaProjection(w).u.vol.left = left;
  668.       MesaProjection(w).u.vol.right = right;
  669.       MesaProjection(w).u.vol.bottom = bottom;
  670.       MesaProjection(w).u.vol.top = top;
  671.       MesaProjection(w).u.vol.near = near;
  672.       MesaProjection(w).u.vol.far = far;
  673.     }
  674. }
  675.  
  676. void
  677. GLwSetOrthoProjection (Widget w,
  678.              GLdouble left, GLdouble right,
  679.              GLdouble bottom, GLdouble top,
  680.              GLdouble near, GLdouble far)
  681. {
  682.   if (is_workstation (w))
  683.     {
  684.       MesaProjection(w).type = ORTHO;
  685.       MesaProjection(w).u.vol.left = left;
  686.       MesaProjection(w).u.vol.right = right;
  687.       MesaProjection(w).u.vol.bottom = bottom;
  688.       MesaProjection(w).u.vol.top = top;
  689.       MesaProjection(w).u.vol.near = near;
  690.       MesaProjection(w).u.vol.far = far;
  691.     }
  692. }
  693.  
  694. GLuint
  695. GLwGetProjectionList (Widget w)
  696. {
  697.   if (is_workstation (w))
  698.     {
  699.       if (MesaProjection(w).type == PROJ_LIST)
  700.     return MesaProjection(w).list;
  701.     }
  702.   return 0;
  703. }
  704.  
  705. int
  706. GLwGetProjectionMatrix (Widget w, GLdouble *m)
  707. {
  708.   if (is_workstation (w))
  709.     {
  710.       if (MesaProjection(w).type == PROJ_MATRIX)
  711.     memcpy (m, MesaProjection(w).u.m, sizeof (MesaProjection(w).u.m));
  712.       return 1;
  713.     }
  714.   return 0;
  715. }
  716.  
  717. void
  718. GLwRedrawObjects (Widget w)
  719. {
  720.   if (is_workstation (w))
  721.     {
  722.       XMesaBuffer buffer;
  723.       XMesaContext context;
  724.  
  725.       GLwMakeCurrent(w);
  726.       buffer = XMesaGetCurrentBuffer();
  727.       context = XMesaGetCurrentContext();
  728.  
  729.       XMesaMakeCurrent (MesaContext (w), MesaBuffer (w));
  730.       if (MesaProjection(w).type != NOPROJ)
  731.     {
  732.       glMatrixMode (GL_PROJECTION);
  733.       glPushMatrix ();
  734.       glLoadIdentity ();
  735.     }
  736.       switch (MesaProjection(w).type)
  737.     {
  738.     case PROJ_MATRIX:
  739.       glLoadMatrixd (MesaProjection(w).u.m);
  740.       break;
  741.     case PROJ_LIST:
  742.       if (!glIsList (MesaProjection(w).list))
  743.         XtAppWarning (XtWidgetToApplicationContext (w),
  744.               "Invalid projection list!");
  745.       else
  746.         glCallList (MesaProjection(w).list);
  747.       break;
  748.     case FRUSTUM:
  749.       mesa_frustum (MesaProjection(w).u.vol);
  750.       break;
  751.     case ORTHO:
  752.       mesa_ortho (MesaProjection(w).u.vol);
  753.       break;
  754.     case NOPROJ:
  755.       break;
  756.     }
  757.       glMatrixMode (GL_MODELVIEW);
  758.       glPushMatrix ();
  759.       {
  760.     GLuint *obj;
  761.     glLoadIdentity ();
  762.     switch (MesaView(w).type)
  763.       {
  764.       case PROJ_MATRIX:
  765.         glLoadMatrixd (MesaView(w).u.m);
  766.         break;
  767.       case PROJ_LIST:
  768.         if (!glIsList (MesaView(w).list))
  769.           XtAppWarning (XtWidgetToApplicationContext (w),
  770.                 "Invalid view list!");
  771.         else
  772.           glCallList (MesaView(w).list);
  773.         break;
  774.       case LOOK_AT:
  775.         mesa_look_at (MesaView(w).u.look_at);
  776.         break;
  777.       case POLAR:
  778.         mesa_polar (MesaView(w).u.polar);
  779.         break;
  780.       case NOVIEW:
  781.         break;
  782.       }
  783.     for (obj = MesaObjects (w); obj < MesaNextObject (w); obj++)
  784.       {
  785.         if (!glIsList (*obj))
  786.           XtAppWarning (XtWidgetToApplicationContext (w),
  787.                 "Invalid object list!");
  788.         else
  789.           {
  790.         glPushMatrix ();
  791.           glCallList (*obj);
  792.         glPopMatrix ();
  793.           }
  794.       }         
  795.       }
  796.       glPopMatrix ();
  797.       if (MesaProjection(w).type != NOVIEW)
  798.     {
  799.       glMatrixMode (GL_PROJECTION);
  800.       glPopMatrix ();
  801.       glMatrixMode (GL_MODELVIEW);
  802.     }
  803.       glFinish ();
  804.       XMesaSwapBuffers (buffer);
  805.       XMesaMakeCurrent (context, buffer);
  806.     }
  807. }
  808.  
  809. /* obsolete aliases: */
  810.  
  811. void
  812. GLwPostView (Widget w, GLuint view)
  813. {
  814.   GLwPostViewList (w, view);
  815. }
  816.  
  817. GLuint
  818. GLwGetView (Widget w)
  819. {
  820.   return GLwGetViewList (w);
  821. }
  822.  
  823. void
  824. GLwPostProjection (Widget w, GLuint proj)
  825. {
  826.   GLwPostProjectionList (w, proj);
  827. }
  828.  
  829. GLuint
  830. GLwGetProjection (Widget w)
  831. {
  832.   return GLwGetProjectionList (w);
  833. }
  834.  
  835. /* The End. */
  836.  
  837.